home *** CD-ROM | disk | FTP | other *** search
- /* GNU Emacs routines to deal with char tables.
- Copyright (C) 1987, 1990 Free Software Foundation, Inc.
-
- This file is part of GNU Emacs.
-
- GNU Emacs is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the GNU Emacs General Public
- License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- GNU Emacs, but only under the conditions described in the
- GNU Emacs General Public License. A copy of this license is
- supposed to have been given to you along with GNU Emacs so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies. */
-
- /* Written by:
- Howard Gayle
- TN/ETX/TT/HL
- Ericsson Telecom AB
- S-126 25 Stockholm
- Sweden
- howard@ericsson.se
- uunet!ericsson.se!howard
- Phone: +46 8 719 5565
- FAX : +46 8 719 8439
- */
-
- #include "config.h"
- #include "lisp.h"
- #include "chartab.h"
- #include "etctab.h"
- #include "buffer.h"
-
- Lisp_Object Qchar_table_p;
- Lisp_Object Vbackslash_char_table;
- Lisp_Object Vctl_arrow_char_table;
-
- extern Lisp_Object build_string ();
- extern Lisp_Object intern ();
-
- #define MAXGLYFSTR 22 /* Max chars in a glyf. */
- #define GLYF_DELTA 1024 /* Grow glyf table by this many bytes each time. */
-
- char_t *glyf_table;
- char_t *glyf_next; /* Next free position in glyf_table. */
- int glyf_table_size; /* Size of glyf table in bytes. */
- int glyf_space_left; /* Current free bytes in glyf table. */
- glyf_t max_glyf; /* Maximum legal glyf_t. */
-
- extern Lisp_Object Vxterm;
-
- DEFUN ("new-glyf", Fnew_glyf, Snew_glyf, 1, 1, 0,
- "Return a newly created glyf for the given string.")
- (s)
- Lisp_Object s; /* String. */
- {
- register int l; /* String length. */
- register char_t *p; /* Misc. pointer. */
- register Lisp_Object z;
-
- CHECK_STRING (s, 0);
- l = XSTRING (s)->size;
-
- #ifdef HAVE_X_WINDOWS
- if (!NULL (Vxterm))
- {
- if (1 != l) arg_out_of_range (s);
- XFASTINT (z) = (1 << 8) | XSTRING(s)->data[0];
- return (z);
- }
- #endif
-
- if ((l < 1) || (l > MAXGLYFSTR)) arg_out_of_range (s);
- while (l > glyf_space_left)
- {
- p = (char_t *) xrealloc ((long *) glyf_table, glyf_table_size + GLYF_DELTA);
- glyf_table = p;
- glyf_table_size += GLYF_DELTA;
- glyf_space_left += GLYF_DELTA;
- glyf_next = p + max_glyf + glyf_len (max_glyf) + 1;
- }
- p = glyf_next;
- if ((p - glyf_table) <= max_glyf) abort ();
- max_glyf = p - glyf_table;
- *p++ = l;
- bcopy (XSTRING(s)->data, p, l);
- glyf_next = p + l;
- glyf_space_left -= l + 1;
- XFASTINT (z) = max_glyf;
- return (z);
- }
-
- DEFUN ("find-glyf", Ffind_glyf, Sfind_glyf, 1, 1, 0,
- "Return the glyf for the given string, or nil if there is none.")
- (s)
- Lisp_Object s; /* String. */
- {
- register int l; /* String length. */
- register char_t *p; /* Steps through glyf table. */
- register char_t *q; /* End of glyf table. */
- register char_t *sd; /* String data. */
- register Lisp_Object z;
-
- CHECK_STRING (s, 0);
- l = XSTRING (s)->size;
- sd = XSTRING (s)->data;
-
- #ifdef HAVE_X_WINDOWS
- if (!NULL (Vxterm))
- {
- if (1 != l) arg_out_of_range (s);
- XFASTINT (z) = (1 << 8) | *sd;
- return (z);
- }
- #endif
-
- if ((l < 1) || (l > MAXGLYFSTR)) arg_out_of_range (s);
- p = glyf_table + SPACEGLYF;
- q = glyf_next;
- while ((p < q) && ((l != *p) || strncmp (p + 1, sd, l)))
- p += *p + 1;
- if (p >= q)
- return (Qnil);
- else
- {
- XFASTINT (z) = p - glyf_table;
- return (z);
- }
- }
-
- DEFUN ("get-glyf", Fget_glyf, Sget_glyf, 1, 1, 0,
- "Return the glyf for the given string, or make one if there is none.")
- (s)
- Lisp_Object s; /* String. */
- {
- register Lisp_Object g = Ffind_glyf (s);
-
- return (NULL (g) ? Fnew_glyf (s) : g);
- }
-
- DEFUN ("glyf-stats", Fglyf_stats, Sglyf_stats, 0, 0, 0,
- "Return (max_glyf glyf_table_size glyf_space_left).")
- ()
- {
- return (Fcons (XFASTINT (max_glyf),
- Fcons (XFASTINT (glyf_table_size),
- Fcons (XFASTINT (glyf_space_left), Qnil))));
- }
-
- int
- glyf_len (g)
- register glyf_t g;
- {
- register int l;
-
- if (g < SPACEGLYF) abort ();
- if (g > max_glyf) abort ();
-
- #ifdef HAVE_X_WINDOWS
- if (!NULL (Vxterm)) return (1);
- #endif
-
- l = glyf_table[g];
- if (l > MAXGLYFSTR) abort ();
- return (l);
- }
-
- char_t *
- glyf_str (g)
- register glyf_t g;
- {
- static char_t b[2]; /* For X windows glyf.*/
-
- if (g < SPACEGLYF) abort ();
- if (g > max_glyf) abort ();
-
- #ifdef HAVE_X_WINDOWS
- if (!NULL (Vxterm))
- {
- b[0] = 0377 & g;
- return (b);
- }
- #endif
-
- return (glyf_table + g + 1);
- }
-
- /* Return the glyf_t encoded by a Lisp integer. Check for errors. */
- static glyf_t
- get_glyf_arg (obj)
- register Lisp_Object obj;
- {
- register int i;
-
- CHECK_NUMBER (obj, 1);
- i = XINT (obj);
- if ((i < SPACEGLYF) || (i > max_glyf)) arg_out_of_range (obj);
- return ((glyf_t) i);
- }
-
- DEFUN ("glyf-to-string", Fglyf_to_string, Sglyf_to_string, 1, 1, 0,
- "Return the bytes of glyf G.")
- (obj)
- Lisp_Object obj;
- {
- register glyf_t g = get_glyf_arg (obj);
-
- return (make_string (glyf_str (g), glyf_len (g)));
- }
-
- DEFUN ("char-table-p", Fchar_table_p, Schar_table_p, 1, 1, 0,
- "Return t iff ARG is a char_table.")
- (obj)
- Lisp_Object obj;
- {
- return ((XTYPE (obj) == Lisp_Chartab) ? Qt : Qnil);
- }
-
- Lisp_Object
- check_char_table (obj)
- Lisp_Object obj;
- {
- register Lisp_Object tem;
-
- while (tem = Fchar_table_p (obj), NULL (tem))
- obj = wrong_type_argument (Qchar_table_p, obj, 0);
- return (obj);
- }
-
- DEFUN ("backslash-char-table",
- Fbackslash_char_table, Sbackslash_char_table, 0, 0, 0,
- "Return the backslash char table.")
- ()
- {
- return (Vbackslash_char_table);
- }
-
- DEFUN ("ctl-arrow-char-table",
- Fctl_arrow_char_table, Sctl_arrow_char_table, 0, 0, 0,
- "Return the ctl-arrow char table.")
- ()
- {
- return (Vctl_arrow_char_table);
- }
-
-
- DEFUN ("copy-char-table", Fcopy_char_table, Scopy_char_table, 0, 1, 0,
- "Construct a new char table and return it.\n\
- It is a copy of the TABLE, which defaults to default-buffer-char-table.")
- (table)
- Lisp_Object table;
- {
- register struct Lisp_Chartab *ot; /* Old char table. */
- register struct Lisp_Chartab *nt; /* New char table. */
- register Lisp_Object z; /* Return. */
-
- if (NULL (table)) table = buffer_defaults.buffer_char_table;
- table = check_char_table (table);
- ot = XCHARTAB (table);
- z = make_etc_table (sizeof (struct Lisp_Chartab), Lisp_Chartab);
- nt = XCHARTAB (z);
- bcopy (((char *) &ot->ct_frameg), ((char *) &nt->ct_frameg),
- sizeof (struct Lisp_Chartab) - sizeof (struct Lisp_Etctab));
- return (z);
- }
-
- DEFUN ("get-char-table-invisc",
- Fget_char_table_invisc, Sget_char_table_invisc, 1, 1, 0,
- "Return the selective display character of the given char table.")
- (char_table)
- register Lisp_Object char_table;
- {
- register Lisp_Object invisc;
-
- char_table = check_char_table (char_table);
- XFASTINT (invisc) = XCHARTAB (char_table)->ct_invisc;
- return (invisc);
- }
-
- DEFUN ("get-char-table-frameg",
- Fget_char_table_frameg, Sget_char_table_frameg, 1, 1, 0,
- "Return the frame glyf of the given char table.")
- (char_table)
- register Lisp_Object char_table;
- {
- register Lisp_Object frameg;
-
- char_table = check_char_table (char_table);
- XFASTINT (frameg) = XCHARTAB (char_table)->ct_frameg;
- return (frameg);
- }
-
- DEFUN ("get-char-table-truncg",
- Fget_char_table_truncg, Sget_char_table_truncg, 1, 1, 0,
- "Return the truncation glyf of the given char table.")
- (char_table)
- register Lisp_Object char_table;
- {
- register Lisp_Object truncg;
-
- char_table = check_char_table (char_table);
- XFASTINT (truncg) = XCHARTAB (char_table)->ct_truncg;
- return (truncg);
- }
-
- DEFUN ("get-char-table-wrapg",
- Fget_char_table_wrapg, Sget_char_table_wrapg, 1, 1, 0,
- "Return the wrap glyf of the given char table.")
- (char_table)
- register Lisp_Object char_table;
- {
- register Lisp_Object wrapg;
-
- char_table = check_char_table (char_table);
- XFASTINT (wrapg) = XCHARTAB (char_table)->ct_wrapg;
- return (wrapg);
- }
-
- DEFUN ("get-char-table-invisr",
- Fget_char_table_invisr, Sget_char_table_invisr, 1, 1, 0,
- "Return the selective display rope of the given char_table.")
- (char_table)
- register Lisp_Object char_table;
- {
- register Lisp_Object invisr;
- register Lisp_Object len;
- register struct Lisp_Vector *p;
- register int index;
-
- char_table = check_char_table (char_table);
- XFASTINT (len) = XCHARTAB (char_table)->ct_invisr.r_len;
- invisr = Fmake_vector (len, Qnil);
- p = XVECTOR (invisr);
- for (index = 0; index < XINT (len); index++)
- p->contents[index] =
- XFASTINT (XCHARTAB (char_table)->ct_invisr.r_glyfs[index]);
- return (invisr);
- }
-
- DEFUN ("get-char-table-dispr",
- Fget_char_table_dispr, Sget_char_table_dispr, 2, 2, 0,
- "Return the terminal display rope in the given char table\n\
- for the given character.")
- (char_table, chr)
- register Lisp_Object char_table;
- register Lisp_Object chr;
- {
- register Lisp_Object dispr;
- register Lisp_Object len;
- register struct Lisp_Vector *p;
- register int index;
- register struct Lisp_Chartab *cp;
- register glyf_t *q; /* Steps through the rope. */
- register char_t c; /* The character. */
-
- char_table = check_char_table (char_table);
- c = get_char_arg (chr);
- cp = XCHARTAB (char_table);
- XFASTINT (len) = ROPE_LEN (c, cp);
- dispr = Fmake_vector (len, Qnil);
- p = XVECTOR (dispr);
- q = cp->ct_dispr[c].r_glyfs;
- for (index = 0; index < XFASTINT (len); index++)
- p->contents[index] = XFASTINT (*q++);
- return (dispr);
- }
-
- DEFUN ("put-char-table-invisc",
- Fput_char_table_invisc, Sput_char_table_invisc, 2, 2, 0,
- "Set the selective display character in char table TABLE to C.")
- (char_table, invisc)
- register Lisp_Object char_table;
- register Lisp_Object invisc;
- {
- char_table = check_char_table (char_table);
- XCHARTAB (char_table)->ct_invisc = get_char_arg (invisc);
- return (invisc);
- }
-
- DEFUN ("put-char-table-frameg",
- Fput_char_table_frameg, Sput_char_table_frameg, 2, 2, 0,
- "Set the frame glyf in char table TABLE to G.")
- (char_table, frameg)
- register Lisp_Object char_table;
- register Lisp_Object frameg;
- {
- char_table = check_char_table (char_table);
- XCHARTAB (char_table)->ct_frameg = get_glyf_arg (frameg);
- return (frameg);
- }
-
- DEFUN ("put-char-table-truncg",
- Fput_char_table_truncg, Sput_char_table_truncg, 2, 2, 0,
- "Set the truncation glyf in char table TABLE to G.")
- (char_table, truncg)
- register Lisp_Object char_table;
- register Lisp_Object truncg;
- {
- char_table = check_char_table (char_table);
- XCHARTAB (char_table)->ct_truncg = get_glyf_arg (truncg);
- return (truncg);
- }
-
- DEFUN ("put-char-table-wrapg",
- Fput_char_table_wrapg, Sput_char_table_wrapg, 2, 2, 0,
- "Set the line wrap glyf in char table TABLE to G.")
- (char_table, wrapg)
- register Lisp_Object char_table;
- register Lisp_Object wrapg;
- {
- char_table = check_char_table (char_table);
- XCHARTAB (char_table)->ct_wrapg = get_glyf_arg (wrapg);
- return (wrapg);
- }
-
- DEFUN ("put-char-table-invisr",
- Fput_char_table_invisr, Sput_char_table_invisr, 2, 2, 0,
- "Set the selective display rope in char table TABLE to ROPE.")
- (char_table, invisr)
- register Lisp_Object char_table;
- register Lisp_Object invisr;
- {
- register int i;
- register int n;
- register struct Lisp_Vector *p;
-
- char_table = check_char_table (char_table);
- CHECK_VECTOR (invisr, 1);
- p = XVECTOR (invisr);
- n = p->size;
- if (n > MAXROPE) arg_out_of_range (invisr);
- for (i = 0; i != n; ++i)
- get_glyf_arg (p->contents[i]);
- XCHARTAB (char_table)->ct_invisr.r_len = n;
- for (i = 0; i != n; ++i)
- XCHARTAB (char_table)->ct_invisr.r_glyfs[i] = get_glyf_arg (p->contents[i]);
- return (invisr);
- }
-
- DEFUN ("put-char-table-dispr",
- Fput_char_table_dispr, Sput_char_table_dispr, 3, 3, 0,
- "Set the terminal display rope in char table TABLE for\n\
- character C to ROPE.")
- (char_table, chr, disp)
- register Lisp_Object char_table;
- register Lisp_Object chr;
- register Lisp_Object disp;
- {
- register int i;
- register int n;
- register struct Lisp_Vector *p;
- register rope_t *rp;
-
- char_table = check_char_table (char_table);
- CHECK_VECTOR (disp, 2);
- p = XVECTOR (disp);
- n = p->size;
- if (n > MAXROPE) arg_out_of_range (disp);
- for (i = 0; i != n; ++i)
- get_glyf_arg (p->contents[i]);
- rp = &(XCHARTAB (char_table)->ct_dispr[get_char_arg (chr)]);
- rp->r_len = n;
- for (i = 0; i != n; ++i)
- rp->r_glyfs[i] = get_glyf_arg (p->contents[i]);
- return (disp);
- }
-
- static void
- init_char_table_common (e, r)
- register glyf_t (*e)(); /* Function to turn one character into a glyf.*/
- int r; /* Flag set for reinitialization.*/
- {
- register struct Lisp_Chartab *cp;
- register rope_t *rp;
- register int i;
-
- /* Initialization of backslash char table: */
- if (!r)
- Vbackslash_char_table =
- make_etc_table (sizeof (struct Lisp_Chartab), Lisp_Chartab);
- cp = XCHARTAB (Vbackslash_char_table);
- cp->ct_frameg = (*e) ('|');
- cp->ct_truncg = (*e) ('$');
- cp->ct_wrapg = (*e) ('\\');
- cp->ct_invisc = '\r';
- rp = &cp->ct_invisr;
- rp->r_len = 4;
- rp->r_glyfs[0] = SPACEGLYF;
- rp->r_glyfs[1] = (*e) ('.');
- rp->r_glyfs[2] = (*e) ('.');
- rp->r_glyfs[3] = (*e) ('.');
- rp = cp->ct_dispr;
- for (i = 0; i != 256; ++i)
- {
- rp->r_len = 4;
- rp->r_glyfs[0] = (*e) ('\\');
- rp->r_glyfs[1] = (*e) (((i >> 6) & 07) + '0');
- rp->r_glyfs[2] = (*e) (((i >> 3) & 07) + '0');
- rp->r_glyfs[3] = (*e) (((i >> 0) & 07) + '0');
- ++rp;
- }
- rp = &cp->ct_dispr[' '];
- rp->r_len = 1;
- rp->r_glyfs[0] = SPACEGLYF;
- ++rp;
- for (i = '!'; i <= '~'; ++i)
- {
- rp->r_len = 1;
- rp->r_glyfs[0] = (*e) (i);
- ++rp;
- }
-
- /* Initialization of ctl-arrow char table: */
- if (!r)
- Vctl_arrow_char_table =
- make_etc_table (sizeof (struct Lisp_Chartab), Lisp_Chartab);
- cp = XCHARTAB (Vctl_arrow_char_table);
- cp->ct_frameg = (*e) ('|');
- cp->ct_truncg = (*e) ('$');
- cp->ct_wrapg = (*e) ('\\');
- cp->ct_invisc = '\r';
- rp = &cp->ct_invisr;
- rp->r_len = 4;
- rp->r_glyfs[0] = SPACEGLYF;
- rp->r_glyfs[1] = (*e) ('.');
- rp->r_glyfs[2] = (*e) ('.');
- rp->r_glyfs[3] = (*e) ('.');
- rp = cp->ct_dispr;
- for (i = 0; i != ' '; ++i)
- {
- rp->r_len = 2;
- rp->r_glyfs[0] = (*e) ('^');
- rp->r_glyfs[1] = (*e) (i ^ 0100);
- ++rp;
- }
- rp = &cp->ct_dispr[' '];
- rp->r_len = 1;
- rp->r_glyfs[0] = SPACEGLYF;
- ++rp;
- for (i = '!'; i <= '~'; ++i)
- {
- rp->r_len = 1;
- rp->r_glyfs[0] = (*e) (i);
- ++rp;
- }
- rp = &cp->ct_dispr[0177];
- rp->r_len = 2;
- rp->r_glyfs[0] = (*e) ('^');
- rp->r_glyfs[1] = (*e) ('?');
- ++rp;
- for (i = 128; i != 256; ++i)
- {
- rp->r_len = 4;
- rp->r_glyfs[0] = (*e) ('\\');
- rp->r_glyfs[1] = (*e) (((i >> 6) & 07) + '0');
- rp->r_glyfs[2] = (*e) (((i >> 3) & 07) + '0');
- rp->r_glyfs[3] = (*e) (((i >> 0) & 07) + '0');
- ++rp;
- }
- }
-
- /* Glyf corresponding to char c: */
- static glyf_t
- englyf (c)
- char_t c;
- {
- return ((c - ' ') * 2 + SPACEGLYF);
- }
-
- init_char_table_once ()
- {
- register char_t *p;
- register int i;
-
- init_char_table_common (englyf, 0);
-
- /* Initialization of glyf table: */
- glyf_table = (char_t *) malloc (GLYF_DELTA - 16);
- if (!glyf_table) memory_full();
- p = glyf_table;
-
- for (i = 0; i != SPACEGLYF; i += 2)
- {
- *p++ = 1;
- *p++ = '?';
- }
-
- for (i = ' '; i != 0177; ++i)
- {
- *p++ = 1;
- *p++ = i;
- }
- glyf_next = p;
- glyf_table_size = GLYF_DELTA - 16;
- glyf_space_left = GLYF_DELTA - 16 - (p - glyf_table);
- max_glyf = (p - glyf_table) - 2;
- }
-
- #ifdef HAVE_X_WINDOWS
- static glyf_t
- englyfx (c)
- char_t c;
- {
- return ((1 << 8) + c);
- }
-
- init_char_table_x ()
- {
- init_char_table_common (englyfx, 1);
- max_glyf = 0xffff;
- }
- #endif
-
- /* The following routine is to be used in xdisp. For copying the
- ** overlay arrow string into a glyf table.
- ** This is a HACK to fix a bug, nothing else.
- */
-
- glyf_t
- char_to_glyf (c)
- char c;
- {
- #ifdef HAVE_X_WINDOWS
- if (!NULL (Vxterm))
- {
- return (englyfx (c));
- }
- #endif
- return (englyf (c));
- }
-
- syms_of_char_table ()
- {
- Qchar_table_p = intern ("char-table-p");
- staticpro (&Qchar_table_p);
- staticpro (&Vbackslash_char_table);
- staticpro (&Vctl_arrow_char_table);
-
- defsubr (&Snew_glyf);
- defsubr (&Sfind_glyf);
- defsubr (&Sget_glyf);
- defsubr (&Sglyf_to_string);
- defsubr (&Sglyf_stats);
- defsubr (&Schar_table_p);
- defsubr (&Sbackslash_char_table);
- defsubr (&Sctl_arrow_char_table);
- defsubr (&Scopy_char_table);
- defsubr (&Sget_char_table_invisc);
- defsubr (&Sget_char_table_frameg);
- defsubr (&Sget_char_table_truncg);
- defsubr (&Sget_char_table_wrapg);
- defsubr (&Sget_char_table_invisr);
- defsubr (&Sget_char_table_dispr);
- defsubr (&Sput_char_table_invisc);
- defsubr (&Sput_char_table_frameg);
- defsubr (&Sput_char_table_truncg);
- defsubr (&Sput_char_table_wrapg);
- defsubr (&Sput_char_table_invisr);
- defsubr (&Sput_char_table_dispr);
- }
-